/*
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package top.continew.admin.common.service.impl;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.continew.admin.common.config.properties.CloudStorageProperties;
import top.continew.admin.common.service.CloudStorageService;
import top.continew.admin.common.util.CloudStorageUtils;
import top.continew.starter.core.exception.BusinessException;

import java.io.InputStream;

/**
 * 腾讯云COS存储服务实现
 *
 * @author Charles7c
 * @since 2025/1/15 10:00
 */
@Slf4j
@Service
@EnableConfigurationProperties(CloudStorageProperties.class)
@ConditionalOnProperty(prefix = "cloud-storage-config.tencent-cos", name = "enabled", havingValue = "true")
public class TencentCosStorageServiceImpl implements CloudStorageService {

    private final COSClient cosClient;
    private final CloudStorageProperties.TencentCos tencentCosConfig;

    public TencentCosStorageServiceImpl(CloudStorageProperties cloudStorageProperties) {
        this.tencentCosConfig = cloudStorageProperties.getTencentCos();
        this.cosClient = initCosClient();
    }

    @Override
    public String upload(InputStream inputStream, String fileName) {
        try {
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(inputStream.available());
            
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                tencentCosConfig.getBucketName(), 
                fileName, 
                inputStream, 
                metadata
            );
            
            cosClient.putObject(putObjectRequest);
            return getFileUrl(fileName);
        } catch (Exception e) {
            log.error("腾讯云COS文件上传失败: {}", e.getMessage(), e);
            throw new BusinessException("文件上传失败");
        }
    }

    @Override
    public String upload(MultipartFile file) {
        try {
            String fileName = CloudStorageUtils.generateFileName(file.getOriginalFilename());
            return upload(file.getInputStream(), fileName);
        } catch (Exception e) {
            log.error("腾讯云COS文件上传失败: {}", e.getMessage(), e);
            throw new BusinessException("文件上传失败");
        }
    }

    @Override
    public void delete(String fileName) {
        try {
            cosClient.deleteObject(tencentCosConfig.getBucketName(), fileName);
        } catch (Exception e) {
            log.error("腾讯云COS文件删除失败: {}", e.getMessage(), e);
            throw new BusinessException("文件删除失败");
        }
    }

    @Override
    public String getFileUrl(String fileName) {
        return String.format("https://%s.cos.%s.myqcloud.com/%s", 
            tencentCosConfig.getBucketName(), 
            tencentCosConfig.getRegion(), 
            fileName);
    }

    private COSClient initCosClient() {
        COSCredentials cred = new BasicCOSCredentials(
            tencentCosConfig.getSecretId(), 
            tencentCosConfig.getSecretKey()
        );
        
        Region region = new Region(tencentCosConfig.getRegion());
        ClientConfig clientConfig = new ClientConfig(region);
        
        return new COSClient(cred, clientConfig);
    }
}